﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using intelliEssay.Interop.FontServices;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Wordprocessing;

namespace intelliEssay.Interop
{
    /// <summary>
    /// This is a shorthand wrapper for RunInfo.
    /// Internally, a RunInfo is built using Helper.GetRunInfo(). 
    /// <para>This implementation is subject to change as is on 12.22</para>
    /// </summary>
    public class RunInfoEx
    {
        RunInfo runInfo;
        public RunInfoEx(WordprocessingDocument wd, Run run, HostApplications hostApplication = HostApplications.MsOffice2010)
        {
            intelliEssay.Interop.FontServices.RunInfoHelper helper = new RunInfoHelper(wd);
            // do not care about compiler warning. Internal use of helper is allowed.
            runInfo = helper.GetRunInfo(run);
        }
        /// <summary>
        /// Queries run-related information.
        /// This internally calls RunInfo properties.
        /// </summary>
        /// <param name="propertyName">the property name of RunInfo in query</param>
        /// <returns>the value of the property</returns>
        /// <remarks>Reflection is not used due to effeciency issues.</remarks>
        public dynamic this[string propertyName]
        {
            get
            {
                propertyName = propertyName.ToLowerInvariant();
                switch (propertyName)
                {
                    case "characterscale":
                        return runInfo.CharacterScale;
                    case "color":
                        return runInfo.Color;
                    case "runfonts":
                        return runInfo.Font;
                    case "fontsize":
                        return runInfo.FontSize;
                    case "isbold":
                    case "bold":
                    case "w:b":
                        return runInfo.IsBold;
                    case "isitalic":
                    case "italic":
                    case "w:i":
                        return runInfo.IsItalic;
                    case "isunderline":
                    case "underline":
                    case "w:u":
                        return runInfo.IsUnderline;
                    case "text":
                        return runInfo.Text;
                    case "verticaltextalignment":
                        return runInfo.VerticalPositionAlignment;
                    case "spacing":
                    case "w:s":
                        return runInfo.Spacing;
                    default:
                        throw new NotImplementedException("The query for property " + propertyName + " isn't supported in this build");
                }
            }
        }


        public bool SemanticEquals(RunInfoEx other, out List<string> unequalAttributes)
        {
            unequalAttributes = new List<string>();
            if (this.runInfo.CharacterScale != other.runInfo.CharacterScale)
            {
                unequalAttributes.Add("characterscale");
            }
            if (this.runInfo.Color != other.runInfo.Color)
            {
                unequalAttributes.Add("color");
            }
            if (this.runInfo.FontFamily != other.runInfo.FontFamily)
            {
                unequalAttributes.Add("fontfamily");
            }
            if (this.runInfo.FontSize != other.runInfo.FontSize)
            {
                unequalAttributes.Add("fontsize");
            }
            if (this.runInfo.IsBold != other.runInfo.IsBold)
            {
                unequalAttributes.Add("isbold");
            }
            if (this.runInfo.IsItalic != other.runInfo.IsItalic)
            {
                unequalAttributes.Add("isitalic");
            }
            if (this.runInfo.IsUnderline != other.runInfo.IsUnderline)
            {
                unequalAttributes.Add("isunderline");
            }
            if (this.runInfo.Spacing != other.runInfo.Spacing)
            {
                unequalAttributes.Add("spacing");
            }
            if (this.runInfo.VerticalPositionAlignment != other.runInfo.VerticalPositionAlignment)
            {
                unequalAttributes.Add("verticaltextalignment");
            }
            return unequalAttributes.Count == 0;
        }

        public dynamic GetSemanticValue(string memberName)
        {
            if (memberName != "fontsize")
            {
                return this[memberName];
            }
            return (int.Parse(runInfo.FontSize) / 2).ToString();
        }
    }
}
